<!-- Created by jack on 2022/2/12 - 16:54 -->
<style scoped lang="less">
.window{
  min-width: v-bind(minWidth);
  min-height: v-bind(minHeight);
  position: absolute;
  width: v-bind(width);
  height: v-bind(height);
  top: v-bind(top);
  left: v-bind(left);
  z-index: v-bind(zIndex);
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 8px 20px 5px rgba(20, 27, 39, 0.14);
  &-focus{ box-shadow: 0 15px 25px 5px rgba(20, 27, 39, 0.34)}
  // 侧边栏左右两侧布局
  &__aside{
    display: flex;
    flex-direction: row;
    &__aside{
      width: 200px;
      height: 100%!important;
      user-select: none;
      background: v-bind(asideBgColor);
      position: relative;
      max-width: v-bind(asideMaxWidth);
      min-width: v-bind(asideMinWidth);
      //z-index: 1;
      &__header{
        height: 45px;
        display: flex;
        align-items: center;
        padding-left: 10px;
        position: relative;
        //z-index: 1;
      }
      &-blur{
        box-shadow: 1px 0 10px 1px rgba(20, 27, 39, 0.1);
        filter: opacity(0.96) grayscale(60%);
      }
      &__right-border{
        position: absolute;
        right: 0;
        height: 100%;
        width: 2px;
        cursor: ew-resize;
      }
    }
    &__content{
      &__header{
        height: 45px;
        display: flex;
        align-items: center;
        position: relative;
      }
      background: v-bind(contentBgColor);
      flex: 1;
      width: 100%;
      position: relative;
      height: 100%;
      &-blur{
        background: v-bind(contentBgColor);
        filter: opacity(0.96) grayscale(60%);
      }
    }
  }
  // 顶部底部布局
  &__content{
    &__header{
      user-select: none;
      width: 100%;
      height: v-bind(contentHeaderHeight);
      background: v-bind(contentHeaderBgColor);
      display: flex;
      align-items: center;
      padding: 0 12px;
      font-size: 14px!important;
      color: grey!important;
      font-weight: 600!important;
      position: relative;
      white-space: nowrap;
      &__title{
        height: 100%;
        width: 100%;
        &__label{
          color: v-bind(titleColor);
          width: calc(100% - 120px);
          text-align: center;
        }
        &-blur{
          filter: grayscale(100%);
        }
      }
      &-blur{
        filter: opacity(0.8);
      }
    }
    &__content{
      width: 100%;
      position: relative;
      height: calc(100% - 24px);
    }
  }

}
.transition{
  transition: all ease-in-out 300ms;
}
.close{
  animation: close-animation 250ms  linear 0s  1  forwards;
}
.min-size{
  animation: min-size-animation 500ms  linear 0s  1  forwards;
}
@keyframes close-animation {
  from {
    opacity: 1;
  }
  to{
    transform-origin: left bottom;
    transform: rotate(-45deg) scale(0.3);
    opacity: 0;
  }
}
@keyframes min-size-animation{
  from {
    opacity: 1;
  }
  to{
    transform: translateY(800px) scale(0.3);
    opacity: 0;
  }
}
</style>

<template >
    <!-- 左右分栏样式 -->
  <div ref="windowRef" :id="appId" :class="{ 'window-focus':focusSign, transition:useTransition ,'close':showCloseAnimation}" class="window window__aside" v-if="type==='aside'" :tabindex="tabIndex" @focus="focusSign = true" >
    <!--  边框    -->
    <windowBorder :id="appId" :focus="focusSign" :min-height="minHeight" :min-width="minWidth"/>
    <!--  左侧  -->
    <div class="window__aside__aside"  :class="{'window__aside__aside-blur':!focusSign}" :id="asideId">
      <div class="window__aside__aside__header" :id="asideHeaderId">
        <windowController @close="closeWindow" @min="minWindow" @max="maxWindow" :focusSign="focusSign"/>
        <slot name="aside-header"></slot>
      </div>
      <div class="window__aside__aside__right-border" :id="asideBorderId"/>
      <slot name="aside"></slot>
    </div>
    <!--  右侧  -->
    <div class="window__aside__content"  :class="{'window__aside__content-blur':!focusSign}">
      <div class="window__aside__content__header" :id="contentHeaderId">
        <slot name="content-header"></slot>
      </div>
      <slot name="content"></slot>
    </div>
    <slot />
  </div>

    <!-- 默认窗口样式  -->
    <div ref="windowRef" :id="appId" :class="{ 'window-focus':focusSign,transition:useTransition ,'close':showCloseAnimation}" class="window window__content" v-else :tabindex="tabIndex"  >
      <!--  边框    -->
      <windowBorder :id="appId" :focus="focusSign" :min-height="minHeight" :min-width="minWidth"/>
      <!--  头部  -->
      <div class="window__content__header" :id="contentHeaderId" :class="{'window__content__header-blur':!focusSign}">
        <windowController @close="closeWindow" @min="minWindow" @max="maxWindow" :focusSign="focusSign"/>
        <slot name="content-header"  class="window__content__header__title">
          <div class="window__content__header__title__label">{{title}}</div>
        </slot>
      </div>
      <!--    主内容  -->
      <div class="window__content__content">
        <slot name="content"></slot>
      </div>
      <slot />
    </div>
</template>

<script lang="ts" setup>
import html2canvas from 'html2canvas'; // 转最小化图片

import windowController from './component/windowController.vue'
import windowBorder from './component/windowBorder.vue'
import {getDom, getDomPosition, moveDom, resizeDom, setDomRect} from "@/helper";
import {computed, nextTick, onBeforeUpdate, onMounted, ref, watch} from 'vue'
import {setTimer} from "@/helper";
import { DomPosition } from "@/helper";
import  WindowStore  from "./store";
import DockBarStore from '@/application/dockBar/src/store'
const dockBarStore = DockBarStore()
const props = defineProps({
  windowConfig:{ type:Object, default:() => ({}) },
  type:{ type:String, default:'default' }, // 盒子模型 1、default => 上下分割，顶部header条，底部content。2、aside => 左右分割，左侧侧边栏，右侧content。
  tabIndex: { type:Number, default: 0 }, // 窗口tabIndex
  id:{ type:String,default:'window' } // 窗口id
})
const windowStore = WindowStore() // pinia
const emit = defineEmits(['close','max','min'])

/** 位置 */
const top = computed( _=> (props?.windowConfig?.top || '200px')) // 顶部
const left = computed( _=> (props?.windowConfig?.left || '20%')) // 左侧
const width = computed( _=> (props?.windowConfig?.width || '600px')) // 宽度
const minWidth = computed( _=> (props?.windowConfig?.minWidth || '300px')) // 宽度
const height = computed( _=> (props?.windowConfig?.height || '400px')) // 高度
const minHeight = computed( _=> (props?.windowConfig?.height || '200px')) // 高度

/** content属性 */
const title = computed( _=> (props?.windowConfig?.title ||  '无标题')) // 图标地址
const titleColor = computed( _=> (props?.windowConfig?.titleColor ||  '#000')) // 标题颜色
const contentHeaderBgColor = computed( _=> (props?.windowConfig?.contentHeaderBgColor ||  '#f8f3f7')) // 顶部背景颜色
const contentBgColor = computed( _=> (props?.windowConfig?.contentBgColor ||  '#fff')) // 背景颜色
const contentHeaderHeight = computed( _=> (props?.windowConfig?.contentHeaderHeight || '24px')) // header高度
/** aside属性 */
const asideBgColor = computed( _=> (props?.windowConfig?.asideBgColor || '#f8f3f7'))
const asideMinWidth = computed( _=> (props?.windowConfig?.asideMinWidth || '60px'))
const asideMaxWidth = computed( _=> (props?.windowConfig?.asideMaxWidth || '60%'))

/** 控制id */
const appId = computed( _ => props?.id + '-@' +  Math.round(new Date().getTime() / 1000)) // content样式头部id
const contentHeaderId = computed( _ => (props?.id + Math.round(new Date().getTime() / 1000) + '-contentHeader')) // content样式头部id
const asideId = computed( _ => (props?.id + '-@' + Math.round(new Date().getTime() / 1000) + '-aside')) // aside 侧边id
const asideHeaderId = computed( _ => (props?.id + '-@' + Math.round(new Date().getTime() / 1000) + '-asideHeader')) // aside 侧边header id
const asideBorderId = computed( _ => (props?.id  + '-@' + Math.round(new Date().getTime() / 1000) + '-asideBorder'))// aside 侧边拖拽 id

/** 聚焦状态 */
const focusSign = ref(false)
onMounted( () => { focusSign.value = true })

/** 定位层级更改 */
const storeZIndex = windowStore.$state.zIndex
let zIndex = ref(storeZIndex)// 层级索引
watch(focusSign,(value) => {
  if(value){
    zIndex.value = windowStore.$state.zIndex + 1
    windowStore.setZIndex(zIndex.value)
    windowStore.addOpenWindowList(appId.value)
  }
})

/** 关闭 */
const showCloseAnimation = ref(false)
const closeWindow = () => {
  showCloseAnimation.value = true
  emit('close')
  const windowItem = Array.from(windowStore.$state.minSizeList).find( ( ele:any) => ele.id === appId.value )
  if(!windowItem){
    setTimer(() => {
      document.getElementById(appId.value)?.remove()
      windowStore.removeOpenWindowById(appId.value)
    },300,1)
  }
}
/** 最小化 */
let windowRef = ref()
const minWindow = ( ) => {
  /** 生成图片 */
  const dom = document.getElementById(appId.value)
  if (dom) {
    emit('min')
    dom?.classList.add('min-size')
    windowStore.addMinSizeList({id: appId.value, windowRef, zIndex})
    setTimer(() => {
      zIndex.value = -10000
      focusSign.value = false
    }, 500, 1)
    return
    // html2canvas(dom, {
    //   useCORS: true,
    //   allowTaint: false,
    //   logging: false,
    //   letterRendering: true
    // }).then((canvas) => {
    //   const img = canvas.toDataURL('image/png')
    //   emit('min')
    //   windowStore.addMinSizeList({id: appId.value, img, windowRef, zIndex})
    //   const imageId = `dock-image-${appId.value}`
    //   dom?.classList.add('min-size')
    //   setTimer(() => {
    //     zIndex.value = -10000
    //     focusSign.value = false
    //   }, 500, 1)
    // })
  }

}

/** 最大化窗口 */
let useTransition = ref(false) // 设置过度属性
let isMax = ref(false) // 最大化状态标识
let maxBefore: DomPosition | null // 切换最大化之前样式
const maxWindow = () => {
  useTransition.value = true
  if(!isMax.value){ // 未全屏状态
    emit('max')
    isMax.value = true
    maxBefore = getDomPosition('#' + appId.value)
    const dockBarPosition = getDomPosition('#' + 'dockBar')
    setDomRect('#' + appId.value,'100vw',`calc(100vh - ${dockBarPosition.height}px - ${dockBarStore.$state.gap}px)`,0,0,)
  }else{
    isMax.value = false
    setDomRect('#' + appId.value,maxBefore.width,maxBefore.height,maxBefore.left,maxBefore.top,)
  }
  setTimer(() => { useTransition.value = false },300,1)
}



/* 设置dom移动 */
onBeforeUpdate( () => {
  const dom = getDom(`#${appId.value}`)
  document.addEventListener('mousedown',(event:MouseEvent) => {
    const { path } = event
    focusSign.value = path?.includes(dom);
  })
  moveDom('#' + asideHeaderId.value,'#' + appId.value)
  moveDom('#' +contentHeaderId.value,'#' + appId.value)
  resizeDom('#' +asideBorderId.value,'#' + asideId.value,'row')
})

</script>
